#include <d3dx10.h>
#include "GShaderDX10.h"
#include "../Texture/Texture2DDX10.h"

CGShaderDX10::CGShaderDX10( mString a_sFileName )
: CGShader(a_sFileName)
{
    m_pShader          = NULL;
    m_pShaderDebugInfo = NULL;
}

CGShaderDX10::~CGShaderDX10( )
{
    SAFE_RELEASE(m_pShaderDebugInfo);
    SAFE_RELEASE(m_pShader);
}

mVoid CGShaderDX10::Compile( )
{
    if (m_pShader != NULL)
        return;

    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders.
    // Setting this flag improves the shader debugging experience, but still allows 
    // the shaders to be optimized and to run exactly the way they will run in 
    // the release configuration of this program.
    dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif

    ID3D10Blob          *pShaderCode;
    D3DX10CompileFromFileA(m_sFileName.c_str(), 
        NULL, &CID3D10Include::g_D3D10Include, "main", "ps_4_0", dwShaderFlags, 0, NULL, 
        &pShaderCode, &m_pShaderDebugInfo, NULL );
    if (m_pShaderDebugInfo != NULL)
    {
        //debug
        mChar *ErrorStr = (mChar*)m_pShaderDebugInfo->GetBufferPointer();
        (*g_pDebug) << "{Shader compile error: \n" << ErrorStr << "\n";
    }
    g_D3DDevice.pD3D10Device->CreateGeometryShader(pShaderCode->GetBufferPointer(), 
        pShaderCode->GetBufferSize(), 
        &m_pShader);

    Init(pShaderCode);
    SAFE_RELEASE(pShaderCode);
}

mBool CGShaderDX10::SendConstantValue( const std::string &a_sConstName, mVoid *a_pValue, size_t a_ValueSize, TChangeFreq a_ChangeFreq )
{
    return CConstantStorageDX10::SendConstantValue(a_sConstName, a_pValue, a_ValueSize, a_ChangeFreq);
}

mBool CGShaderDX10::SendTexture( const std::string &a_sTextureName, CTexture2D *a_pTexture )
{
    CTexture2DDX10 *pTexDX10 = static_cast<CTexture2DDX10*>(a_pTexture);
    return CConstantStorageDX10::AddResource(a_sTextureName, pTexDX10->TextureSRV());
}

mVoid CGShaderDX10::Bind( )
{
    /* Updating buffers */
    UpdateConstantValues();
    if (CConstantStorageDX10::m_uNumResources)
        g_D3DDevice.pD3D10Device->GSSetShaderResources(0, CConstantStorageDX10::m_uNumResources, CConstantStorageDX10::m_ppSRV);
    if (m_ppBuffers)
        g_D3DDevice.pD3D10Device->GSSetConstantBuffers(0, ChangeFreqLast, m_ppBuffers);
    g_D3DDevice.pD3D10Device->GSSetShader(m_pShader);
}